home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / macros / texinfo / util / deref.c < prev    next >
C/C++ Source or Header  |  1994-01-28  |  5KB  |  239 lines

  1. /*
  2.  * deref.c
  3.  
  4.  *  compile command:  gcc -g -o deref deref.c
  5.  
  6.  *  execute command:  deref filename.texi > newfile.texi
  7.  
  8.  * To: bob@gnu.ai.mit.edu
  9.  * Subject: another tool
  10.  * Date: 18 Dec 91 16:03:13 EST (Wed)
  11.  * From: gatech!skeeve!arnold@eddie.mit.edu (Arnold D. Robbins)
  12.  *
  13.  * Here is deref.c.  It turns texinfo cross references back into the
  14.  * one argument form. It has the same limitations as fixref; one xref per
  15.  * line and can't cross lines.  You can use it to find references that do
  16.  * cross a line boundary this way:
  17.  *
  18.  *     deref < manual > /dev/null 2>errs
  19.  *
  20.  * (This assumes bash or /bin/sh.)  The file errs will have list of lines
  21.  * where deref could not find matching braces.
  22.  *
  23.  * A gawk manual processed by deref goes through makeinfo without complaint.
  24.  * Compile with gcc and you should be set.
  25.  *
  26.  * Enjoy,
  27.  *
  28.  * Arnold
  29.  * -----------
  30.  */
  31.  
  32. /*
  33.  * deref.c
  34.  *
  35.  * Make all texinfo references into the one argument form.
  36.  *
  37.  * Arnold Robbins
  38.  * arnold@skeeve.atl.ga.us
  39.  * December, 1991
  40.  *
  41.  * Copyright, 1991, Arnold Robbins
  42.  */
  43.  
  44. /*
  45.  * LIMITATIONS:
  46.  *    One texinfo cross reference per line.
  47.  *    Cross references may not cross newlines.
  48.  *    Use of fgets for input (to be fixed).
  49.  */
  50.  
  51. #include <stdio.h>
  52. #include <ctype.h>
  53. #include <errno.h>
  54.  
  55. /* for gcc on the 3B1, delete if this gives you grief */
  56. extern int fclose (FILE * fp);
  57. extern int fprintf (FILE * fp, const char *str,...);
  58.  
  59. extern char *strerror (int errno);
  60. extern char *strchr (char *cp, int ch);
  61. extern int strncmp (const char *s1, const char *s2, int count);
  62.  
  63. extern int errno;
  64.  
  65. void process (FILE * fp);
  66. void repair (char *line, char *ref, int toffset);
  67.  
  68. int Errs = 0;
  69. char *Name = "stdin";
  70. int Line = 0;
  71. char *Me;
  72.  
  73. /* main --- handle arguments, global vars for errors */
  74.  
  75. int
  76. main (int argc, char **argv)
  77. {
  78.   FILE *fp;
  79.  
  80.   Me = argv[0];
  81.  
  82.   if (argc == 1)
  83.     process (stdin);
  84.   else
  85.     for (argc--, argv++; *argv != NULL; argc--, argv++)
  86.       {
  87.     if (argv[0][0] == '-' && argv[0][1] == '\0')
  88.       {
  89.         Name = "stdin";
  90.         Line = 0;
  91.         process (stdin);
  92.       }
  93.     else if ((fp = fopen (*argv, "r")) != NULL)
  94.       {
  95.         Name = *argv;
  96.         Line = 0;
  97.         process (fp);
  98.         fclose (fp);
  99.       }
  100.     else
  101.       {
  102.         fprintf (stderr, "%s: can not open: %s\n",
  103.              *argv, strerror (errno));
  104.         Errs++;
  105.       }
  106.       }
  107.   return Errs != 0;
  108. }
  109.  
  110. /* isref --- decide if we've seen a texinfo cross reference */
  111.  
  112. int
  113. isref (char *cp)
  114. {
  115.   if (strncmp (cp, "@ref{", 5) == 0)
  116.     return 5;
  117.   if (strncmp (cp, "@xref{", 6) == 0)
  118.     return 6;
  119.   if (strncmp (cp, "@pxref{", 7) == 0)
  120.     return 7;
  121.   return 0;
  122. }
  123.  
  124. /* process --- read files, look for references, fix them up */
  125.  
  126. void
  127. process (FILE * fp)
  128. {
  129.   char buf[BUFSIZ];
  130.   char *cp;
  131.   int count;
  132.  
  133.   while (fgets (buf, sizeof buf, fp) != NULL)
  134.     {
  135.       Line++;
  136.       cp = strchr (buf, '@');
  137.       if (cp == NULL)
  138.     {
  139.       fputs (buf, stdout);
  140.       continue;
  141.     }
  142.       do
  143.     {
  144.       count = isref (cp);
  145.       if (count == 0)
  146.         {
  147.           cp++;
  148.           cp = strchr (cp, '@');
  149.           if (cp == NULL)
  150.         {
  151.           fputs (buf, stdout);
  152.           goto next;
  153.         }
  154.           continue;
  155.         }
  156.       /* got one */
  157.       repair (buf, cp, count);
  158.       break;
  159.     }
  160.       while (cp != NULL);
  161.     next:;
  162.     }
  163. }
  164.  
  165. /* repair --- turn all texinfo cross references into the one argument form */
  166.  
  167. void
  168. repair (char *line, char *ref, int toffset)
  169. {
  170.   int braces = 1;        /* have seen first left brace */
  171.   char *cp;
  172.  
  173.   ref += toffset;
  174.  
  175.   /* output line up to and including left brace in reference */
  176.   for (cp = line; cp <= ref; cp++)
  177.     putchar (*cp);
  178.  
  179.   /* output node name */
  180.   for (; *cp && *cp != '}' && *cp != ',' && *cp != '\n'; cp++)
  181.     putchar (*cp);
  182.  
  183.   if (*cp != '}')
  184.     {                /* could have been one arg xref */
  185.       /* skip to matching right brace */
  186.       for (; braces > 0; cp++)
  187.     {
  188.       switch (*cp)
  189.         {
  190.         case '@':
  191.           cp++;        /* blindly skip next character */
  192.           break;
  193.         case '{':
  194.           braces++;
  195.           break;
  196.         case '}':
  197.           braces--;
  198.           break;
  199.         case '\n':
  200.         case '\0':
  201.           Errs++;
  202.           fprintf (stderr,
  203.                "%s: %s: %d: mismatched braces\n",
  204.                Me, Name, Line);
  205.           goto out;
  206.         default:
  207.           break;
  208.         }
  209.     }
  210.     out:
  211.       ;
  212.     }
  213.  
  214.   putchar ('}');
  215.   if (*cp == '}')
  216.     cp++;
  217.  
  218.   /* now the rest of the line */
  219.   for (; *cp; cp++)
  220.     putchar (*cp);
  221.   return;
  222. }
  223.  
  224. /* strerror --- return error string, delete if in your library */
  225.  
  226. char *
  227. strerror (int errno)
  228. {
  229.   static char buf[100];
  230.   extern int sys_nerr;
  231.   extern char *sys_errlist[];
  232.  
  233.   if (errno < sys_nerr && errno >= 0)
  234.     return sys_errlist[errno];
  235.  
  236.   sprintf (buf, "unknown error %d", errno);
  237.   return buf;
  238. }
  239.